import { HttpProxy } from './HttpProxy'
// import { utils } from "../helpers/utils";

type APIQueryArgCollection = ApiTypes.APIQueryArgCollection
type APIBodyArgCollection = ApiTypes.APIBodyArgCollection
type ApiBaseResult<T extends object = {}> = ApiTypes.ApiBaseResult<T>

function asyncWrap<T extends ApiBaseResult>(method: 'GET' | 'POST',
                                            path: string,
                                            urlArgs?: APIQueryArgCollection,
                                            bodyArgs?: APIBodyArgCollection): Promise<T> {
  const proxy = new HttpProxy<T>(method, path, urlArgs, bodyArgs).preventDefault()
  return new Promise<T>((ok, fail) => {
    proxy.success((res) => {
      return ok(res)
    }).fail(() => {
      fail({ errcode: 50050, errmsg: 'http error' })
    })
  })
}

export namespace api {
  export const AUTH_ERROR_CODES = HttpProxy.AUTH_ERROR_CODES

  function get<T extends ApiBaseResult>(
    path: string,
    urlArgs?: APIQueryArgCollection
  ): Promise<T> {
    return asyncWrap('GET', path, urlArgs)
  }

  function post<T extends ApiBaseResult>(
    path: string,
    urlArgs?: APIQueryArgCollection,
    bodyArgs?: APIBodyArgCollection
  ): Promise<T> {
    return asyncWrap('POST', path, urlArgs, bodyArgs)
  }

  export function postBinary<T = {}>(
    path: string,
    urlArgs: APIQueryArgCollection,
    binary: Blob | string
  ): HttpProxy<T> {
    // TODO post binary was not fully supported yet! it can't be called from front end!
    return new HttpProxy<T>('POST', path, urlArgs, binary)
  }

  /**
   * 后台登录
   * @param username 用户名
   * @param password 密码
   */
  export function login(username: string, password: string) {
    return post<ApiBaseResult<DataModels.LoginResponse>>('/login', {}, { username, password })
  }

  /**
   * 创建学生基础档案
   * @param student 学生信息
   */
  export function createStudent(student: PostDataTypes.Student) {
    return post<ApiBaseResult<{ id: string }>>('/student/create', {}, student)
  }

  /**
   * 获取学生列表
   * @param offset 偏移量
   * @param count 一页多少
   */
  export function getStudentList(offset: number, count: number) {
    return get<ApiBaseResult<{ list: DataModels.StudentModel[] }>>('/student/list', { offset, count })
  }

  /**
   * 获取单个学生信息
   * @param id 学生id
   */
  export function getStudentById(id: number) {
    return get<ApiBaseResult<{ student: DataModels.StudentModel }>>('/student/one', { id })
  }

  /**
   * 更新学生信息
   * @param id 学生id
   * @param student 需要更新的学生信息
   */
  export function updateStudentInfo(id: number, student: Partial<PostDataTypes.Student>) {
    return post<ApiBaseResult>('/student/update', { id }, { ...student })
  }

  /**
   * 创建学生个人锦集
   * @param studentId 学生id
   * @param words 学生个人锦集
   */
  export function createStudentWorks(studentId: number, words: PostDataTypes.StudentDetails) {
    return post<ApiBaseResult>('/student/works/create', { studentId }, { ...words })
  }

  /**
   * 获取学生的所有的作品
   * @param studentId 学生 id
   */
  export function getStudentDetailList(studentId: number) {
    return post<ApiBaseResult<{ list: DataModels.StudentDetailModel[] }>>('/student/works/list', { studentId })
  }

  /**
   * 创建科目
   * @param data 创建科目的数据
   */
  export function createSubject(data: PostDataTypes.DanceClassData) {
    return post<ApiBaseResult<{ id: number }>>('/subject/create', {}, data)
  }

  /**
   * 获取班级的 list
   * @param offset 偏移
   * @param count 每页的数量
   */
  export function getDanceClassList(offset: number, count: number) {
    return get<ApiBaseResult<{ list: DataModels.DanceClassModel[] }>>('/subject/list', { offset, count })
  }

  /**
   * 获取单个科目的数据
   * @param id 科目的 id
   */
  export function getDanceClassById(id: number) {
    return get<ApiBaseResult<{ subject: DataModels.DanceClassModel }>>('/subject/one', { id })
  }

  export function updateSubjectInfo(id: number, data: Partial<PostDataTypes.DanceClassData>) {
    return post<ApiBaseResult>('/subject/update', { id }, data)
  }
}

export default api
